{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# CPSC 330 final exam\n",
    "\n",
    "The University of British Columbia\n",
    "\n",
    "Instructor: Mike Gelbart\n",
    "\n",
    "April 24, 2020"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Instructions\n",
    "\n",
    "#### What is / is not allowed.\n",
    "\n",
    "- This exam is open book. You are welcome to consult the course materials, online resources, etc.\n",
    "- You are allowed to copy/adapt/reuse code from the course materials (lectures, my homework solutions, your homework solutions) **with attribution**.\n",
    "  - For each of the coding questions, there is a section underneath that asks you to list the resources you borrowed code from. \n",
    "  - Using code from the course materials without attribution may be considered academic misconduct.\n",
    "- You are **not** allowed to copy/adapt/reuse code from anywhere other than course materials.\n",
    "  - Using code from anywhere other than the course materials will be considered academic misconduct.\n",
    "- You are **not** allowed to copy text, visualizations, or anything other than code from anywhere.\n",
    "- You are **not** allowed to communicate with **anyone else, in any way** during the exam. \n",
    "  - This includes talking in-person, phone, text, chat apps, screen sharing, email, sharing your notebook, or any form of communication. \n",
    "  - This restriction applies to any other person, regardless of whether or not they are enrolled in CPSC 330.\n",
    "\n",
    "#### Submission instructions.\n",
    "\n",
    "- You will receive and submit your exam notebook the same way you submit your homework, through github.students.cs.ubc.ca. \n",
    "- As with the homework assignments, **you must ensure that all your code outputs (scores, tables, figures, etc.) are displayed in the notebook**. For example, if you are required to calculate some value, it is not sufficient to just store the value to a variable, nor is it sufficient to have a `print(value)` in your code - the print code must actually be run and the notebook saved, so that the output is shown on the screen when the notebook is rendered. This allows us see your results without running your code. \n",
    "  - When you are done, take a look at your rendered notebook in a web browser at github.students.cs.ubc.ca, to make sure all the output is displayed properly.\n",
    "- **It is essential that you commit and push your work to GitHub frequently.** If you have a connection problem at the end of the exam and you miss the deadline, we will grade your latest work that was successfully pushed. Thus, if you only try to push once at the end and something goes wrong, you will not have a submission and will receive zero. You have been warned.\n",
    "- You will gain read and write access to your repository at 12:00pm. You will lose write access to your repository at 2:30pm.\n",
    "- Answer the questions directly in this notebook, in the same way that you would for an assignment.\n",
    "\n",
    "#### System requirements.\n",
    "\n",
    "- You will need a computer with Python 3, Jupyter, and the main Python packages we have used in the course, such as pandas, scikit-learn, matplotlib, etc. \n",
    "- You will not need any of the \"extra\" packages in the course, such as graphviz, pandas_profiling, tensorflow, gensim, xgboost, lightgbm, catboost, lifelines, shap, etc.\n",
    "- If you are using the same system as you used for the homework assignments, you should be fine.\n",
    "- If you are using a new or different system than the one you used during the course, please make sure you can run all the homework solutions before the exam starts. \n",
    "- I have tried to create the exam such that you don't need to do any heavy-duty computations. \n",
    "  - If something is running too slowly on your machine, try something else and just add a quick note explaining that the code was too slow.\n",
    "\n",
    "#### Questions and announcements.\n",
    "\n",
    "- If I need to make any announcements or clarifications during the exam, I will post them as followup discussions on [this Piazza thread](https://piazza.com/class/k1gx4b3djbv3ph?cid=388).\n",
    "- You are responsible for monitoring Piazza for any announcements or clarifications.\n",
    "- If you have questions during the exam, send me a **private** post on Piazza. \n",
    "  - I have enabled private posts.\n",
    "  - I will check Piazza regularly during the exam.\n",
    "  - I will respond through the same private message thread on Piazza.\n",
    "  - I will answer questions in the order they are received. \n",
    "  \n",
    "#### Contingency plans.\n",
    "\n",
    "- In the unlikely event that Piazza goes down during the exam, I will post announcements at the top of the course website README [here](https://github.students.cs.ubc.ca/cpsc330-2019w-t2/home). If you have a private question, email me at mgelbart@cs.ubc.ca.\n",
    "- In the unlikely event that github.students.cs.ubc.ca goes down during the start of the exam, I will distribute the exam by posting it on Piazza.\n",
    "- In the unlikely event that github.students.cs.ubc.ca goes down at the end of the exam, email your completed exam to mgelbart@cs.ubc.ca before the end time.\n",
    "  - **Please do not** email me the exam if github.students.cs.ubc.ca is working. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Integrity Pledge\n",
    "\n",
    "This is an online exam without invigilation. I, and your fellow classmates, are trusting you to approach this exam honourably and abide by the rules. The two main problems with cheating are (1) you might get caught and (2) you are permanently changing your path through your life in a way that you may later regret. \n",
    "\n",
    "IMHO it is easier to recover from a low grade than it is to recover from being a person who conducted themselves dishonestly. In case you disagree with me on that, hopefully problem (1) will deter you from cheating. \n",
    "\n",
    "We will be using the integrity pledge wording set out by the Faculty of Science:\n",
    "\n",
    "> I hereby pledge that I have read and will abide by the rules, regulations, and expectations set out in the Academic Calendar, with particular attention paid to:\n",
    "> 1. [The Student Declaration](http://www.calendar.ubc.ca/vancouver/index.cfm?tree=3,285,0,0)\n",
    "> 2. [The Academic Honesty and Standards](http://www.calendar.ubc.ca/vancouver/index.cfm?tree=3,286,0,0)\n",
    "> 3. [The Student Conduct During Examinations](http://www.calendar.ubc.ca/vancouver/index.cfm?tree=3,41,90,0)\n",
    "> 4. And any special rules for conduct as set out by the examiner.\n",
    "\n",
    "As far as \"special rules\" are concerned, please refer to the \"What is / is not allowed.\" section in the Instructions above. \n",
    "\n",
    "The following wording is also from the Faculty of Science:\n",
    "\n",
    "> I affirm that I will not give or receive any unauthorized help on this examination, that all work will be my own, and that I will abide by any special rules for conduct set out by the examiner.\n",
    "\n",
    "<font color='red'>**In the markdown cell below, you are required to re-type, or copy/paste, the sentence above, and then \"sign\" your name (i.e. type your full name underneath it).**</font> Please do it now so you don't forget."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "_copy the sentence starting with \"I affirm\" here_\n",
    "\n",
    "_put your name here_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Table of Contents\n",
    "\n",
    "- Q1 (5 points)\n",
    "- Q2 (5 points)\n",
    "- Q3 (15 points) \n",
    "- Q4 (20 points)\n",
    "- Q5 (10 points)\n",
    "- Q6 (20 points)\n",
    "- Q7 (25 points)\n",
    "\n",
    "Total: 100 points."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.impute import SimpleImputer\n",
    "from sklearn.compose import ColumnTransformer\n",
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.preprocessing import StandardScaler, OneHotEncoder, FunctionTransformer\n",
    "from sklearn.feature_extraction.text import CountVectorizer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Canadian Cheese Directory\n",
    "\n",
    "In this exam, we will be looking at the [Canadian Cheese Directory dataset](https://open.canada.ca/data/en/dataset/3c16cd48-3ac3-453f-8260-6f745181c83b) from Agriculture and Agri-Food Canada. Because this data is distributed under the [Canadian Open Government License](https://open.canada.ca/en/open-government-licence-canada), I was able to include the data in your final exam repositories, so you should not need to download the dataset. The following code should run:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv(\"canadianCheeseDirectory.csv\", index_col=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will be predicting `FatContentPercent`, which is not available for all the cheeses, so I will first filter out those where this is not available:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = df.dropna(subset=['FatContentPercent'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's take a look at the column names:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['CheeseNameEn', 'CheeseNameFr', 'ManufacturerNameEn',\n",
       "       'ManufacturerNameFr', 'ManufacturerProvCode', 'ManufacturingTypeEn',\n",
       "       'ManufacturingTypeFr', 'WebSiteEn', 'WebSiteFr', 'FatContentPercent',\n",
       "       'MoisturePercent', 'ParticularitiesEn', 'ParticularitiesFr',\n",
       "       'FlavourEn', 'FlavourFr', 'CharacteristicsEn', 'CharacteristicsFr',\n",
       "       'RipeningEn', 'RipeningFr', 'Organic', 'CategoryTypeEn',\n",
       "       'CategoryTypeFr', 'MilkTypeEn', 'MilkTypeFr', 'MilkTreatmentTypeEn',\n",
       "       'MilkTreatmentTypeFr', 'RindTypeEn', 'RindTypeFr', 'LastUpdateDate'],\n",
       "      dtype='object')"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.columns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The columns are duplicated in English and French (e.g. `MilkTypeEn` vs. `MilkTypeFr`). In most cases, this is just duplicated information and we can drop the French columns. However, in two cases we need to first merge the English and French columns because the information may be stored in either column:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "df[\"ManufacturerName\"] = df[\"ManufacturerNameEn\"].fillna(df[\"ManufacturerNameFr\"])\n",
    "df = df.drop(columns=[\"ManufacturerNameEn\", \"ManufacturerNameFr\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "df[\"CheeseName\"] = df[\"CheeseNameEn\"].fillna(df[\"CheeseNameFr\"])\n",
    "df = df.drop(columns=[\"CheeseNameEn\", \"CheeseNameFr\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we're ready to drop all the French columns:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['ManufacturerProvCode', 'ManufacturingTypeEn', 'WebSiteEn',\n",
       "       'FatContentPercent', 'MoisturePercent', 'ParticularitiesEn',\n",
       "       'FlavourEn', 'CharacteristicsEn', 'RipeningEn', 'Organic',\n",
       "       'CategoryTypeEn', 'MilkTypeEn', 'MilkTreatmentTypeEn', 'RindTypeEn',\n",
       "       'LastUpdateDate', 'ManufacturerName', 'CheeseName'],\n",
       "      dtype='object')"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = df.drop(columns=[col for col in df.columns if col.endswith(\"Fr\")])\n",
    "df.columns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we'll do the train/test split:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_train, df_test = train_test_split(df, random_state=123)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "I will start with a bit of exploration:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ManufacturerProvCode</th>\n",
       "      <th>ManufacturingTypeEn</th>\n",
       "      <th>WebSiteEn</th>\n",
       "      <th>FatContentPercent</th>\n",
       "      <th>MoisturePercent</th>\n",
       "      <th>ParticularitiesEn</th>\n",
       "      <th>FlavourEn</th>\n",
       "      <th>CharacteristicsEn</th>\n",
       "      <th>RipeningEn</th>\n",
       "      <th>Organic</th>\n",
       "      <th>CategoryTypeEn</th>\n",
       "      <th>MilkTypeEn</th>\n",
       "      <th>MilkTreatmentTypeEn</th>\n",
       "      <th>RindTypeEn</th>\n",
       "      <th>LastUpdateDate</th>\n",
       "      <th>ManufacturerName</th>\n",
       "      <th>CheeseName</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CheeseId</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1432</th>\n",
       "      <td>QC</td>\n",
       "      <td>Industrial</td>\n",
       "      <td>http://www.damafro.ca/en/home.html</td>\n",
       "      <td>22.0</td>\n",
       "      <td>58.0</td>\n",
       "      <td>Organic</td>\n",
       "      <td>Mild and acidulous</td>\n",
       "      <td>Creamy cheese</td>\n",
       "      <td>Unripened</td>\n",
       "      <td>1</td>\n",
       "      <td>Fresh Cheese</td>\n",
       "      <td>Goat</td>\n",
       "      <td>Pasteurized</td>\n",
       "      <td>No Rind</td>\n",
       "      <td>2016-02-03</td>\n",
       "      <td>Damafro</td>\n",
       "      <td>Chèvre des Alpes BIO</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2281</th>\n",
       "      <td>QC</td>\n",
       "      <td>Artisan</td>\n",
       "      <td>NaN</td>\n",
       "      <td>35.0</td>\n",
       "      <td>33.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Candied fruit flavor with hints of caramel.</td>\n",
       "      <td>NaN</td>\n",
       "      <td>6 months</td>\n",
       "      <td>1</td>\n",
       "      <td>Firm Cheese</td>\n",
       "      <td>Cow</td>\n",
       "      <td>Raw Milk</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2016-02-03</td>\n",
       "      <td>Fromagerie Au Gré des Champs</td>\n",
       "      <td>Frère Chasseur (Le)</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1908</th>\n",
       "      <td>QC</td>\n",
       "      <td>Artisan</td>\n",
       "      <td>NaN</td>\n",
       "      <td>22.0</td>\n",
       "      <td>69.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Unripened</td>\n",
       "      <td>0</td>\n",
       "      <td>Fresh Cheese</td>\n",
       "      <td>Goat</td>\n",
       "      <td>Pasteurized</td>\n",
       "      <td>No Rind</td>\n",
       "      <td>2016-02-03</td>\n",
       "      <td>Fromagerie Couland</td>\n",
       "      <td>Mon précieux</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2224</th>\n",
       "      <td>QC</td>\n",
       "      <td>Artisan</td>\n",
       "      <td>NaN</td>\n",
       "      <td>33.0</td>\n",
       "      <td>33.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>Firm Cheese</td>\n",
       "      <td>Ewe</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Washed Rind</td>\n",
       "      <td>2016-02-03</td>\n",
       "      <td>Maison d'affinage Maurice Dufour (La)</td>\n",
       "      <td>Tomme de Brebis de Charlevoix</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2007</th>\n",
       "      <td>QC</td>\n",
       "      <td>Farmstead</td>\n",
       "      <td>NaN</td>\n",
       "      <td>30.0</td>\n",
       "      <td>42.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Hazelnut flavour</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>Firm Cheese</td>\n",
       "      <td>Cow</td>\n",
       "      <td>Pasteurized</td>\n",
       "      <td>No Rind</td>\n",
       "      <td>2016-02-03</td>\n",
       "      <td>Fromagerie Ferme du littoral</td>\n",
       "      <td>Cheddar Littoral</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         ManufacturerProvCode ManufacturingTypeEn  \\\n",
       "CheeseId                                            \n",
       "1432                       QC          Industrial   \n",
       "2281                       QC             Artisan   \n",
       "1908                       QC             Artisan   \n",
       "2224                       QC             Artisan   \n",
       "2007                       QC           Farmstead   \n",
       "\n",
       "                                   WebSiteEn  FatContentPercent  \\\n",
       "CheeseId                                                          \n",
       "1432      http://www.damafro.ca/en/home.html               22.0   \n",
       "2281                                     NaN               35.0   \n",
       "1908                                     NaN               22.0   \n",
       "2224                                     NaN               33.0   \n",
       "2007                                     NaN               30.0   \n",
       "\n",
       "          MoisturePercent ParticularitiesEn  \\\n",
       "CheeseId                                      \n",
       "1432                 58.0           Organic   \n",
       "2281                 33.0               NaN   \n",
       "1908                 69.0               NaN   \n",
       "2224                 33.0               NaN   \n",
       "2007                 42.0               NaN   \n",
       "\n",
       "                                            FlavourEn CharacteristicsEn  \\\n",
       "CheeseId                                                                  \n",
       "1432                               Mild and acidulous     Creamy cheese   \n",
       "2281      Candied fruit flavor with hints of caramel.               NaN   \n",
       "1908                                              NaN               NaN   \n",
       "2224                                              NaN               NaN   \n",
       "2007                                 Hazelnut flavour               NaN   \n",
       "\n",
       "         RipeningEn  Organic CategoryTypeEn MilkTypeEn MilkTreatmentTypeEn  \\\n",
       "CheeseId                                                                     \n",
       "1432      Unripened        1   Fresh Cheese       Goat         Pasteurized   \n",
       "2281       6 months        1    Firm Cheese        Cow            Raw Milk   \n",
       "1908      Unripened        0   Fresh Cheese       Goat         Pasteurized   \n",
       "2224            NaN        0    Firm Cheese        Ewe                 NaN   \n",
       "2007            NaN        0    Firm Cheese        Cow         Pasteurized   \n",
       "\n",
       "           RindTypeEn LastUpdateDate                       ManufacturerName  \\\n",
       "CheeseId                                                                      \n",
       "1432          No Rind     2016-02-03                                Damafro   \n",
       "2281              NaN     2016-02-03           Fromagerie Au Gré des Champs   \n",
       "1908          No Rind     2016-02-03                     Fromagerie Couland   \n",
       "2224      Washed Rind     2016-02-03  Maison d'affinage Maurice Dufour (La)   \n",
       "2007          No Rind     2016-02-03           Fromagerie Ferme du littoral   \n",
       "\n",
       "                             CheeseName  \n",
       "CheeseId                                 \n",
       "1432               Chèvre des Alpes BIO  \n",
       "2281                Frère Chasseur (Le)  \n",
       "1908                       Mon précieux  \n",
       "2224      Tomme de Brebis de Charlevoix  \n",
       "2007                   Cheddar Littoral  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 781 entries, 1432 to 2391\n",
      "Data columns (total 17 columns):\n",
      " #   Column                Non-Null Count  Dtype  \n",
      "---  ------                --------------  -----  \n",
      " 0   ManufacturerProvCode  781 non-null    object \n",
      " 1   ManufacturingTypeEn   781 non-null    object \n",
      " 2   WebSiteEn             441 non-null    object \n",
      " 3   FatContentPercent     781 non-null    float64\n",
      " 4   MoisturePercent       770 non-null    float64\n",
      " 5   ParticularitiesEn     337 non-null    object \n",
      " 6   FlavourEn             599 non-null    object \n",
      " 7   CharacteristicsEn     491 non-null    object \n",
      " 8   RipeningEn            503 non-null    object \n",
      " 9   Organic               781 non-null    int64  \n",
      " 10  CategoryTypeEn        762 non-null    object \n",
      " 11  MilkTypeEn            780 non-null    object \n",
      " 12  MilkTreatmentTypeEn   732 non-null    object \n",
      " 13  RindTypeEn            543 non-null    object \n",
      " 14  LastUpdateDate        781 non-null    object \n",
      " 15  ManufacturerName      781 non-null    object \n",
      " 16  CheeseName            781 non-null    object \n",
      "dtypes: float64(2), int64(1), object(14)\n",
      "memory usage: 109.8+ KB\n"
     ]
    }
   ],
   "source": [
    "df_train.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, I'll split up the features into the various types:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "numeric_features = ['MoisturePercent']\n",
    "categorical_features = ['ManufacturerProvCode', 'ManufacturingTypeEn', 'Organic', 'CategoryTypeEn', 'MilkTypeEn', 'MilkTreatmentTypeEn', 'RindTypeEn']\n",
    "text_features = ['CheeseName', 'FlavourEn', 'CharacteristicsEn']\n",
    "drop_features = ['WebSiteEn', 'ParticularitiesEn', 'RipeningEn', 'LastUpdateDate', 'ManufacturerName']\n",
    "target_column = 'FatContentPercent'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "assert set(numeric_features + categorical_features + text_features + drop_features + [target_column]) == set(df_train.columns)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Q1: cheese ripening\n",
    "rubric={points:5}\n",
    "\n",
    "I decided to drop the feature `RipeningEn` because it was a hassle to deal with. Here are the unique values of this feature:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['Unripened', '6 months', nan, '3 Months', 'Less than 1 Month',\n",
       "       '2 Months', '9 Months', '2 months', '4 Months',\n",
       "       'More than 5 Years', '2 to 5 year', '6 Months', '2 Years', 'None',\n",
       "       '10 day minimum', '10 days minimum', '1 Month', 'Minimum 10 days',\n",
       "       '4 Years', '3 months', '2 weeks', '30 days', '3 to 6 months',\n",
       "       '1 to 5 year', '1 Year', 'unripened', '18 Months', '6 or 7 weeks',\n",
       "       '90 days', '4 months', '5 Months', '15 Months', '10 days',\n",
       "       '3 Years', '3 years', '30 days in brine', '12 months', '2 days',\n",
       "       '1 month', '10 Months', 'Unriped', '5 days', '45 days', '3 weeks',\n",
       "       '3 to 5 months', '60 days', '5 Years', '1 year', '80 days',\n",
       "       '2-3 months', '5 months', '9 months', 'Not required to ripen.'],\n",
       "      dtype=object)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_train['RipeningEn'].unique()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Describe how you would preprocess this feature into something useful. What type of feature (numeric, categorical, etc) would you end up with? Are there special cases you would need to handle? **Max 3 sentences**."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----------------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Q2: target values\n",
    "rubric={points:5}\n",
    "\n",
    "Make an argument for or against log-transforming the target values in this problem. A good answer will reference this particular problem we're working on, rather than being generally applicable to any problem. **Max 3 sentences.**\n",
    "\n",
    "Note: regardless of your argument, please do **not** transform your targets in the code below, as this would make your exam harder to grade."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "--------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we'll preprocess the features. This should look fairly familiar to you, except for the preprocessing of text features. In [hw5](https://github.students.cs.ubc.ca/cpsc330-2019w-t2/home/blob/master/hw-solutions/hw5/hw5.ipynb) we also mixed text features with other features, but in that case we did not actually put the `CountVectorizer` directly into the `ColumnTransformer`, which I am doing here. Furthermore, there are 3 text columns and I am creating a separate `CountVectorizer` for each one. You do not need to understand every detail, but just understand generally what it does."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train = df_train[target_column]\n",
    "y_test = df_test[target_column]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "numeric_transformer = Pipeline([\n",
    "    ('imputer', SimpleImputer(strategy='median')),\n",
    "    ('scaler', StandardScaler())\n",
    "])\n",
    "\n",
    "categorical_transformer = Pipeline([\n",
    "    ('imputer', SimpleImputer(strategy='constant')),\n",
    "    ('onehot', OneHotEncoder(sparse=False, handle_unknown='ignore'))\n",
    "])\n",
    "\n",
    "# Fit a separate CountVectorizer for each of the text columns.\n",
    "# Need to convert the resulting sparse matrices to dense separately.\n",
    "text_transformer = Pipeline([\n",
    "    ('imputer', SimpleImputer(strategy='constant', fill_value='')),\n",
    "    ('tolist', FunctionTransformer(lambda x: x.ravel(), validate=False)),\n",
    "    ('countvec', CountVectorizer(max_features=10, stop_words='english')),\n",
    "    ('todense', FunctionTransformer(lambda x: x.toarray(), validate=False))\n",
    "])\n",
    "\n",
    "preprocessor = ColumnTransformer([\n",
    "    ('numeric', numeric_transformer, numeric_features),\n",
    "    ('categorical', categorical_transformer, categorical_features)\n",
    "] + [(f, text_transformer, [f]) for f in text_features])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "preprocessor.fit(df_train);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_column_names(preprocessor):\n",
    "    \"\"\"\n",
    "    Gets the feature names from a preprocessor.\n",
    "    This entails looking at the OHE feature names and also\n",
    "    the words used by the CountVectorizers.\n",
    "    \n",
    "    Arguments\n",
    "    ---------\n",
    "    preprocessor: ColumnTransformer\n",
    "        A fit preprocessor following the specific format above.\n",
    "    \n",
    "    Returns\n",
    "    -------\n",
    "    list\n",
    "        A list of column names.\n",
    "    \"\"\"\n",
    "    ohe_feature_names = list(preprocessor.named_transformers_['categorical'].named_steps['onehot'].get_feature_names(categorical_features))\n",
    "    text_feature_names = [f + \"_\" + word for f in text_features for word in preprocessor.named_transformers_[f].named_steps['countvec'].get_feature_names()]\n",
    "    return numeric_features + ohe_feature_names + text_feature_names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>MoisturePercent</th>\n",
       "      <th>ManufacturerProvCode_AB</th>\n",
       "      <th>ManufacturerProvCode_BC</th>\n",
       "      <th>ManufacturerProvCode_MB</th>\n",
       "      <th>ManufacturerProvCode_NB</th>\n",
       "      <th>ManufacturerProvCode_NL</th>\n",
       "      <th>ManufacturerProvCode_NS</th>\n",
       "      <th>ManufacturerProvCode_ON</th>\n",
       "      <th>ManufacturerProvCode_PE</th>\n",
       "      <th>ManufacturerProvCode_QC</th>\n",
       "      <th>...</th>\n",
       "      <th>CharacteristicsEn_cheese</th>\n",
       "      <th>CharacteristicsEn_colored</th>\n",
       "      <th>CharacteristicsEn_creamy</th>\n",
       "      <th>CharacteristicsEn_interior</th>\n",
       "      <th>CharacteristicsEn_pressed</th>\n",
       "      <th>CharacteristicsEn_rind</th>\n",
       "      <th>CharacteristicsEn_ripened</th>\n",
       "      <th>CharacteristicsEn_smooth</th>\n",
       "      <th>CharacteristicsEn_texture</th>\n",
       "      <th>CharacteristicsEn_white</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CheeseId</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1432</th>\n",
       "      <td>1.127656</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>...</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2281</th>\n",
       "      <td>-1.459684</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1908</th>\n",
       "      <td>2.266086</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2224</th>\n",
       "      <td>-1.459684</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2007</th>\n",
       "      <td>-0.528242</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 71 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "          MoisturePercent  ManufacturerProvCode_AB  ManufacturerProvCode_BC  \\\n",
       "CheeseId                                                                      \n",
       "1432             1.127656                      0.0                      0.0   \n",
       "2281            -1.459684                      0.0                      0.0   \n",
       "1908             2.266086                      0.0                      0.0   \n",
       "2224            -1.459684                      0.0                      0.0   \n",
       "2007            -0.528242                      0.0                      0.0   \n",
       "\n",
       "          ManufacturerProvCode_MB  ManufacturerProvCode_NB  \\\n",
       "CheeseId                                                     \n",
       "1432                          0.0                      0.0   \n",
       "2281                          0.0                      0.0   \n",
       "1908                          0.0                      0.0   \n",
       "2224                          0.0                      0.0   \n",
       "2007                          0.0                      0.0   \n",
       "\n",
       "          ManufacturerProvCode_NL  ManufacturerProvCode_NS  \\\n",
       "CheeseId                                                     \n",
       "1432                          0.0                      0.0   \n",
       "2281                          0.0                      0.0   \n",
       "1908                          0.0                      0.0   \n",
       "2224                          0.0                      0.0   \n",
       "2007                          0.0                      0.0   \n",
       "\n",
       "          ManufacturerProvCode_ON  ManufacturerProvCode_PE  \\\n",
       "CheeseId                                                     \n",
       "1432                          0.0                      0.0   \n",
       "2281                          0.0                      0.0   \n",
       "1908                          0.0                      0.0   \n",
       "2224                          0.0                      0.0   \n",
       "2007                          0.0                      0.0   \n",
       "\n",
       "          ManufacturerProvCode_QC  ...  CharacteristicsEn_cheese  \\\n",
       "CheeseId                           ...                             \n",
       "1432                          1.0  ...                       1.0   \n",
       "2281                          1.0  ...                       0.0   \n",
       "1908                          1.0  ...                       0.0   \n",
       "2224                          1.0  ...                       0.0   \n",
       "2007                          1.0  ...                       0.0   \n",
       "\n",
       "          CharacteristicsEn_colored  CharacteristicsEn_creamy  \\\n",
       "CheeseId                                                        \n",
       "1432                            0.0                       1.0   \n",
       "2281                            0.0                       0.0   \n",
       "1908                            0.0                       0.0   \n",
       "2224                            0.0                       0.0   \n",
       "2007                            0.0                       0.0   \n",
       "\n",
       "          CharacteristicsEn_interior  CharacteristicsEn_pressed  \\\n",
       "CheeseId                                                          \n",
       "1432                             0.0                        0.0   \n",
       "2281                             0.0                        0.0   \n",
       "1908                             0.0                        0.0   \n",
       "2224                             0.0                        0.0   \n",
       "2007                             0.0                        0.0   \n",
       "\n",
       "          CharacteristicsEn_rind  CharacteristicsEn_ripened  \\\n",
       "CheeseId                                                      \n",
       "1432                         0.0                        0.0   \n",
       "2281                         0.0                        0.0   \n",
       "1908                         0.0                        0.0   \n",
       "2224                         0.0                        0.0   \n",
       "2007                         0.0                        0.0   \n",
       "\n",
       "          CharacteristicsEn_smooth  CharacteristicsEn_texture  \\\n",
       "CheeseId                                                        \n",
       "1432                           0.0                        0.0   \n",
       "2281                           0.0                        0.0   \n",
       "1908                           0.0                        0.0   \n",
       "2224                           0.0                        0.0   \n",
       "2007                           0.0                        0.0   \n",
       "\n",
       "          CharacteristicsEn_white  \n",
       "CheeseId                           \n",
       "1432                          0.0  \n",
       "2281                          0.0  \n",
       "1908                          0.0  \n",
       "2224                          0.0  \n",
       "2007                          0.0  \n",
       "\n",
       "[5 rows x 71 columns]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_columns = get_column_names(preprocessor)\n",
    "    \n",
    "df_train_enc = pd.DataFrame(preprocessor.transform(df_train), index=df_train.index, columns=new_columns)\n",
    "df_train_enc.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----------------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Q3: initial models\n",
    "rubric={points:15}\n",
    "\n",
    "Let's compare three approaches:\n",
    "\n",
    "1. A baseline model: choose either `DummyClassifier` or `DummyRegressor`, whichever is appropriate for this problem. \n",
    "2. A linear model: choose either `Ridge` or `LogisticRegression`, whichever is appropriate for this problem.\n",
    "3. A random forest model: choose either `RandomForestClassifier` or `RandomForestRegressor`, whichever is appropriate for this problem.\n",
    "\n",
    "For now, just use default hyperparameters.\n",
    "\n",
    "Report the train and cross-validation score in each case. Which model performs best with default hyperparameters?\n",
    "\n",
    "Don't violate the Golden Rule!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-------------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you used code from the course materials (lecture, homework) in the above question, please list what resources you used (e.g. \"Lecture 5\", \"hw5\"). You do not need to specify exactly which lines of code you used, just the resources you took code from.\n",
    "\n",
    "- Resource 1\n",
    "- Resource 2\n",
    "- etc."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-----------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Q4: hyperparameter tuning\n",
    "rubric={points:20}\n",
    "\n",
    "- Using an automated hyperparameter tuning method of your choice, make a reasonable attempt at tuning the hyperperameters for your linear model and random forest model. An excellent solution will also involve tuning the hyperparameters of the preprocessing steps. \n",
    "- Briefly justify your choices of which hyperparameters your tuned and what sorts of values you tried. **Max 3 sentences.**\n",
    "- Briefly discuss your scores after tuning. **Max 3 sentences.**\n",
    "\n",
    "Note: your time is limited, so there is no need to perform large searches that take a long time to run. My code for this question takes about 1.5 minutes to run on my laptop."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you used code from the course materials (lecture, homework) in the above question, please list what resources you used (e.g. \"Lecture 5\", \"hw5\"). You do not need to specify exactly which lines of code you used, just the resources you took code from.\n",
    "\n",
    "- Resource 1\n",
    "- Resource 2\n",
    "- etc."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-----------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Q5: confidence and test set\n",
    "rubric={points:10}\n",
    "\n",
    "- For your best model from Q4, how confident are you in the score you reported? Base your answer on the sub-scores from the different folds of cross-validation. **Max 3 sentences.**\n",
    "- When you are done, compute your score on the test set. Is it what you expected? Briefly discuss. **Max 3 sentences.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you used code from the course materials (lecture, homework) in the above question, please list what resources you used (e.g. \"Lecture 5\", \"hw5\"). You do not need to specify exactly which lines of code you used, just the resources you took code from.\n",
    "\n",
    "- Resource 1\n",
    "- Resource 2\n",
    "- etc."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-----------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Q6: feature importances\n",
    "rubric={points:20}\n",
    "\n",
    "- What are your 5 most important features according to your tuned linear model?\n",
    "- What are your 5 most important features according to your tuned random forest model? \n",
    "- Do they agree with each other? Briefly discuss. **Max 3 sentences.**\n",
    "- Also, briefly discuss one other aspect of the feature importances that you find interesting. **Max 3 sentences.**\n",
    "\n",
    "Note: for the 5 most important features, it is sufficient to display these as code output rather than typing them as text, so long as they are displayed very clearly (i.e. only display those 5, don't leave them as part of a big list). \n",
    "\n",
    "Hint: assuming you've tuned your preprocessor, you'll want to use the `get_columns_names` function provided above because the column names may have changed during hyperparameter tuning."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----------------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you used code from the course materials (lecture, homework) in the above question, please list what resources you used (e.g. \"Lecture 5\", \"hw5\"). You do not need to specify exactly which lines of code you used, just the resources you took code from.\n",
    "\n",
    "- Resource 1\n",
    "- Resource 2\n",
    "- etc."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-----------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Q7: short answer questions\n",
    "rubric={points:25}\n",
    "\n",
    "The following questions are worth 5 points each. These questions refer to specific lectures or homework assignments from the second half of the course. **Max 3 sentences each.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "7(a): [**Lecture 15**](https://github.students.cs.ubc.ca/cpsc330-2019w-t2/home/blob/master/lectures/15_nearest-neighbours.ipynb)\n",
    "\n",
    "Instead of trying to predict the fat content of a cheese, let's say you wanted to solve a different problem: given a query cheese, find similar cheeses in the dataset. How would you approach this problem? Would any of the code above (in this notebook) be useful for this task?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "7(b): [**Lecture 16**](https://github.students.cs.ubc.ca/cpsc330-2019w-t2/home/blob/master/lectures/16_time-series-data.ipynb)\n",
    "\n",
    "In [hw7](https://github.students.cs.ubc.ca/cpsc330-2019w-t2/home/blob/master/hw-solutions/hw7/hw7.ipynb) question 1(e) we used the current week's average avocado price as a baseline prediction for next week's avocado price. Under what circumstances would this approach yield particularly good or bad predictions of next week's avocado price?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "7(c): [**Lecture 17**](https://github.students.cs.ubc.ca/cpsc330-2019w-t2/home/blob/master/lectures/17_survival-analysis.ipynb)\n",
    "\n",
    "In Lecture 17 we looked at a customer churn dataset with a binary target column (yes/no) for whether a customer churned, and a `tenure` column for the length of time. In Lecture 16 we looked at the rain in Australia dataset which has a binary target column (yes/no) for whether it would rain tomorrow and a `Date` column for the time stamp. Both of these are binary classification problems, and both involve changes over time. Why did we have to worry about censoring for the churn dataset but not the rain dataset?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "7(d): [**Lecture 19**](https://github.students.cs.ubc.ca/cpsc330-2019w-t2/home/blob/master/lectures/19_outliers.ipynb)\n",
    "\n",
    "What is the key difference between regression and classification when it comes to outliers? "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "7(e): [**Lecture 21**](https://github.students.cs.ubc.ca/cpsc330-2019w-t2/home/blob/master/lectures/21_communication.ipynb)\n",
    "\n",
    "Consider the following summary I wrote of our cheese analysis, with the target audience of a CPSC 330 student:\n",
    "\n",
    "> In this exam I worked on the [Canadian Cheese Directory dataset](https://open.canada.ca/data/en/dataset/3c16cd48-3ac3-453f-8260-6f745181c83b). I was trying to predict the fat content of a cheese based on numeric features like moisture content, categorical features like the milk type, and text features like the cheese name. I achieved a score of 0.5, which is a lot better than my baseline. And this was all using only 5 folds for cross-validation - imagine how good my model would be with 10 or even 20 folds! I also learned that soft cheeses contain a lot more fat than hard cheeses.\n",
    "\n",
    "Critique this summary. What do you like about it, and what could be improved? Be specific."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----------------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Final checks\n",
    "\n",
    "- [ ] Did you check [Piazza](https://piazza.com/class/k1gx4b3djbv3ph?cid=388) for any announcements or clarifications about the exam? \n",
    "- [ ] Did you complete the integrity pledge near the top of this notebook?\n",
    "- [ ] Did you answer all the questions fully? (Some ask for both code and explanations.)\n",
    "- [ ] Did you make note of any course materials you reused code from, after each coding question?\n",
    "- [ ] Did you keep your answers within the posted length limits (usually 3 sentences)?\n",
    "- [ ] Did you run your notebook from beginning to end (\"Restart Kernel and Run All Cells\") to make sure that your entire notebook runs properly?\n",
    "- [ ] Did you push to github.students.cs.ubc.ca and then view your rendered exam in a web browser?\n",
    "- [ ] Did you make sure all your code output is saved/displayed in the notebook?\n",
    "- [x] Did you read this list of final checks?"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
